//
//  PlayListDetailViewController.swift
//  GhostWorld
//
//  Created by Kam on 2018/5/14.
//  Copyright © 2018 LKGood. All rights reserved.
//

import UIKit

private let nameCellIdentifier = "PlaylistDetailNameCell"
private let opButtonsCellIdentifier = "OpButtonsCell"
private let audioCellIdentifier = "AudioTableCell"

class PlayListDetailViewController: BaseViewController {

  // MARK: - IBOutlets
  
  @IBOutlet weak var tableView: UITableView!
  
  
  // MARK: - Private vars
  
  private var audios: [Audio]?
  
  // MARK: - Private methods
  
  private func prepareUI() {
    tableView.register(UINib(nibName: audioCellIdentifier, bundle: nil), forCellReuseIdentifier: audioCellIdentifier)
    tableView.contentInset = UIEdgeInsets.init(top: 20, left: 0, bottom: 40, right: 0)
    tableView.scrollIndicatorInsets = tableView.contentInset
  }
  
  private func setDownloadAllButtonState(opCell: PlayListOpCell) {
    if let notDownloadedAudios = (audios?.filter { $0.localURL == nil }),
      notDownloadedAudios.count > 0 {
      opCell.isDownloadAllButtonHidden = false
    } else {
      opCell.isDownloadAllButtonHidden = true
    }
  }
  
  private func addNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(downloadFinished(notifiation:)), name: .downloadFinished, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(streamingCacheFinished), name: .streamingCacheFinished, object: nil)
  }
  
  @objc private func downloadFinished(notifiation: Notification) {
    if let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? PlayListOpCell {
      setDownloadAllButtonState(opCell: cell)
    }
  }
  
  @objc private func streamingCacheFinished() {
    if let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? PlayListOpCell {
      setDownloadAllButtonState(opCell: cell)
    }
  }
  
  // MARK: - Public vars
  
  var playlist: Playlist? {
    didSet {
      audios = playlist?.getAudios()
    }
  }
  
  // MARK: - Lifecycle
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    addNotifications()
    prepareUI()
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if let playlist = self.playlist {
      audios = playlist.getAudios()
      tableView.reloadData()
    }
  }
  
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  
  deinit {
    NotificationCenter.default.removeObserver(self)
  }
  
  // MARK: - IBActions
  
  
  
  // MARK: - Public methods
  
  
}

// MARK: - UITableViewDataSource

extension PlayListDetailViewController: UITableViewDataSource {
  
  func numberOfSections(in tableView: UITableView) -> Int {
    return 2
  }
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
      return 2
    case 1:
      return audios?.count ?? 0
    default:
      return 0
    }
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch indexPath.section {
    case 0:
      if indexPath.row == 0 {
        // name cell
        let cell = tableView.dequeueReusableCell(withIdentifier: nameCellIdentifier, for: indexPath) as! PlaylistDetailNameCell
        cell.nameLabel.text = playlist?.name ?? "未命名听单"
        return cell
      } else {
        // op cell
        let cell = tableView.dequeueReusableCell(withIdentifier: opButtonsCellIdentifier, for: indexPath) as! PlayListOpCell
        cell.delegate = self
        setDownloadAllButtonState(opCell: cell)
        return cell
      }
      
    default:
      // audio cell
      let cell = tableView.dequeueReusableCell(withIdentifier: audioCellIdentifier, for: indexPath) as! AudioTableCell
      if let audio = audios?[indexPath.row] {
        cell.prepare(audio: audio)
      }
      return cell
    }
  }
}

// MARK: - UITableViewDelegate

extension PlayListDetailViewController: UITableViewDelegate {
  
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section == 1 {
      if let audio = audios?[indexPath.row],
        let album = audio.album {
        NowPlayingManager.shared.update (
          audioList: audios,
          audioListName: playlist?.name,
          audioLsitType: .playlist,
          audioListRefID: playlist?.id
        )
        NowPlayingManager.shared.play(album: album, audio: audio)
      }
    }
    tableView.deselectRow(at: indexPath, animated: true)
  }
  
  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
      if let audios = self.audios {
        do {
          var newAudios = [Audio]() + audios
          newAudios.remove(at: indexPath.row)
          try playlist?.update(audios: newAudios)
          self.audios!.remove(at: indexPath.row)
          tableView.deleteRows(at: [indexPath], with: .fade)
        } catch let error {
          loggingPrint("Reorder audios of playlist failed. \(error.localizedDescription)")
        }
      }
    }
  }
  
  func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return indexPath.section == 1
  }
  
  func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return indexPath.section == 1
  }
  
  func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    if let sourceAudio = audios?[sourceIndexPath.row] {
      audios?.remove(at: sourceIndexPath.row)
      audios?.insert(sourceAudio, at: destinationIndexPath.row)
      
      do {
        try playlist?.update(audios: audios)
        // update now playing audio list if necessary
        if NowPlayingManager.shared.getAudioListType() == .playlist &&
          NowPlayingManager.shared.getAudioListRefID() == playlist?.id {
          NowPlayingManager.shared.update (audioList: audios)
        }
      } catch let error {
        tableView.moveRow(at: destinationIndexPath, to: sourceIndexPath)
        audios?.remove(at: destinationIndexPath.row)
        audios?.insert(sourceAudio, at: sourceIndexPath.row)
        loggingPrint("Reorder audios of playlist failed. \(error.localizedDescription)")
      }
    }
  }
  
  func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
    return sourceIndexPath.section != proposedDestinationIndexPath.section ?
    sourceIndexPath :
    proposedDestinationIndexPath
  }
  
  func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return 44
  }
  
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == 0 {
      return UITableView.automaticDimension
    } else {
      return 60
    }
  }
}

// MARK: - PlayListOpCellDelegate

extension PlayListDetailViewController: PlayListOpCellDelegate {
  func downloadAllAudios() {
    if let audios = self.audios {
      audios.forEach {
        if $0.localURL == nil && AudioDownloadManager.shared.audioIsInQueue($0) == false {
          AudioDownloadManager.shared.add(audio: $0)
        }
      }
    }
  }
  
  func startEdit() {
    tableView.setEditing(true, animated: true)
  }
  
  func endEdit() {
    tableView.setEditing(false, animated: true)
  }
  
//  func sortAudios() {
//    var newType: AudioSortType = .ascending
//    switch audioSortType {
//    case .ascending:
//      newType = .descending
//    case .descending:
//      newType = .ascending
//    }
//    do {
//      try playlist?.updateAudioSortType(newType)
//      audioSortType = newType
//      tableView.reloadSections(IndexSet(integersIn: 1...1) , with: .automatic)
//    } catch { }
//  }
}
